//    Copyright (C) Kherty.  All rights reserved.
using System.Diagnostics.Contracts;
using System.Reflection;
using System.Windows.Media;
using OpenLS.Core.Serialization;
using System.ComponentModel;

namespace OpenLS.Drawing
{
    ///<summary>
    /// Defines how to fill an area 
    ///</summary>
    public abstract class FillProperties : IOfficeXmlSerializable, INotifyPropertyChanged
    {
        #region IOfficeXmlSerializable Members

        void IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            ReadXmlCore(context);
        }

        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            WriteXmlCore(context);
        }

        #endregion

        internal abstract void ReadXmlCore(ReadContext context);

        internal abstract void WriteXmlCore(WriteContext context);


        internal abstract Brush ToBrush(ColorScheme colorScheme);

        public static FillProperties ReadFillProperties(ReadContext c)
        {
            switch (c.ReaderLocalName)
            {
                case "solidFill":
                    var s = new SolidColorFillProperties();
                    s.ReadXmlCore(c);
                    return s;

                case "gradFill":
                    var g = new GradientFillProperties();
                    g.ReadXmlCore(c);
                    return g;
                case "noFill":
                    var n = new NoFillProperties();
                    n.ReadXmlCore(c);
                    return n;
                case "blipFill":
                    var blipFillProperties = new BlipFillProperties();
                    blipFillProperties.ReadXmlCore(c);
                    return blipFillProperties;
                case "pattFill":
                    var r = new PatternFillProperties();
                    r.ReadXmlCore(c);
                    return r;
                case "grpFill":
                    var gf = new GroupFillProperties();
                    gf.ReadXmlCore(c);
                    return gf;
                default:
                    return null;
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        internal void NotifyPropertyChanged(string propertyName)
        {
            Contract.Requires(GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null);
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }
}